/*
 * Copyright (c) 2020 hebeiyiliuba.com
 * All rights reserved.
 *
 */
package org.jeecg.modules.wlhy.report.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.iterators.CollatingIterator;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.enums.ReportPlatformEnum;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.third.amap.dto.MapDirectionDTO;
import org.jeecg.modules.third.amap.service.AmapService;
import org.jeecg.modules.third.jg.jss.report.cfccapitalflow.entity.CfcCapitalflow;
import org.jeecg.modules.third.jg.jss.report.cfccapitalflow.service.CfcCapitalflowService;
import org.jeecg.modules.third.jg.jss.report.cfccarrierinfo.entity.CfcCarrierinfo;
import org.jeecg.modules.third.jg.jss.report.cfccontractinfo.entity.CfcContractinfo;
import org.jeecg.modules.third.jg.jss.report.cfcdriverinfo.entity.CfcDriverinfo;
import org.jeecg.modules.third.jg.jss.report.cfcdriverinfo.service.CfcDriverinfoService;
import org.jeecg.modules.third.jg.jss.report.cfcgoodsofvehicle.entity.CfcGoodsofvehicle;
import org.jeecg.modules.third.jg.jss.report.cfcjoborderinfo.entity.CfcJoborderinfo;
import org.jeecg.modules.third.jg.jss.report.cfcshipperinfo.entity.CfcShipperinfo;
import org.jeecg.modules.third.jg.jss.report.cfcshipperinfo.service.CfcShipperinfoService;
import org.jeecg.modules.third.jg.jss.report.cfcshippingnoteinfo.entity.CfcShippingnoteinfo;
import org.jeecg.modules.third.jg.jss.report.cfcshippingnoteinfo.service.CfcShippingnoteinfoService;
import org.jeecg.modules.third.jg.jss.report.cfcsourcegoodsinfo.entity.CfcSourcegoodsinfo;
import org.jeecg.modules.third.jg.jss.report.cfcsourcegoodsinfo.service.CfcSourcegoodsinfoService;
import org.jeecg.modules.third.jg.jss.report.cfcvehicleinfo.entity.CfcVehicleinfo;
import org.jeecg.modules.third.jg.jss.report.cfcvehicleinfo.service.CfcVehicleinfoService;
import org.jeecg.modules.third.jg.jss.report.enums.JSV2UploadStatusEnum;
import org.jeecg.modules.third.jg.report.freight.information.constant.JsV2ReportConstant;
import org.jeecg.modules.third.jg.report.freight.information.constant.enums.AhUploadStatusEnum;
import org.jeecg.modules.third.jg.report.freight.information.dto.AppInfoDTO;
import org.jeecg.modules.third.jg.report.freight.information.service.JsuV2ReportPlatformService;
import org.jeecg.modules.third.jg.report.information.model.R;
import org.jeecg.modules.third.openapi.WaybillRouteService;
import org.jeecg.modules.wlhy.bill.entity.HyShippingNoteBill;
import org.jeecg.modules.wlhy.bill.service.IHyShippingNoteBillService;
import org.jeecg.modules.wlhy.company.entity.HyCompany;
import org.jeecg.modules.wlhy.company.entity.HyCompanyConfig;
import org.jeecg.modules.wlhy.company.service.IHyCompanyService;
import org.jeecg.modules.wlhy.customer.entity.HyCustomer;
import org.jeecg.modules.wlhy.customer.entity.HyCustomerCompany;
import org.jeecg.modules.wlhy.customer.service.IHyCustomerAddressReceiveService;
import org.jeecg.modules.wlhy.customer.service.IHyCustomerAddressSendService;
import org.jeecg.modules.wlhy.customer.service.IHyCustomerCompanyService;
import org.jeecg.modules.wlhy.customer.service.impl.HyCustomerServiceImpl;
import org.jeecg.modules.wlhy.hydriver.entity.HyDriver;
import org.jeecg.modules.wlhy.hydriver.entity.HyDriverReport;
import org.jeecg.modules.wlhy.hydriver.service.IHyDriverReportService;
import org.jeecg.modules.wlhy.hydriver.service.IHyDriverService;
import org.jeecg.modules.wlhy.hyinsurance.entity.InsuranceApplyRecord;
import org.jeecg.modules.wlhy.hyinsurance.service.InsuranceApplyRecordService;
import org.jeecg.modules.wlhy.hyvehicle.entity.HyVehicle;
import org.jeecg.modules.wlhy.hyvehicle.entity.HyVehicleReport;
import org.jeecg.modules.wlhy.hyvehicle.entity.HyVehicleType;
import org.jeecg.modules.wlhy.hyvehicle.service.IHyVehicleReportService;
import org.jeecg.modules.wlhy.hyvehicle.service.IHyVehicleService;
import org.jeecg.modules.wlhy.order.entity.HyOrder;
import org.jeecg.modules.wlhy.order.entity.HyOrderDTO;
import org.jeecg.modules.wlhy.order.service.IHyOrderService;
import org.jeecg.modules.wlhy.report.IReportService;
import org.jeecg.modules.wlhy.shipping.constant.ShippingPayStatus;
import org.jeecg.modules.wlhy.shipping.entity.HyShippingNote;
import org.jeecg.modules.wlhy.shipping.entity.WaybillRouteVO;
import org.jeecg.modules.wlhy.shipping.service.IHyShippingNoteService;
import org.jeecg.modules.wlhy.utils.HyCfgUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class JsuV2ReportService implements IReportService {

    @Resource
    private BaseReportService baseReportService;

    @Resource
    private IHyDriverService driverService;

    @Resource
    private IHyVehicleService vehicleService;

    @Autowired
    private IHyCustomerCompanyService customerCompanyService;

    @Autowired
    private IHyShippingNoteService hyShippingNoteService;

    @Autowired
    private IHyShippingNoteBillService hyShippingNoteBillService;

    @Autowired
    private HyCustomerServiceImpl customerService;

    @Resource
    private IHyCustomerAddressSendService customerAddressSendService;

    @Resource
    private IHyCustomerAddressReceiveService customerAddressReceiveService;

    @Autowired
    private JsuV2ReportPlatformService jsuV2ReportPlatformService;

    /**
     * 申报企业信息
     */
    @Autowired
    private IHyCompanyService companyService;


    @Resource
    private IHyDriverReportService hyDriverReportService;


    @Resource
    private IHyVehicleReportService vehicleReportService;

    @Autowired
    private IHyOrderService orderService;

    @Autowired
    private InsuranceApplyRecordService insuranceApplyRecordService;

    @Autowired
    private AmapService amapService;

    /**
     * 江苏省司机信息
     */
    @Resource
    private CfcDriverinfoService driverinfoService;

    /**
     * 江苏省车辆信息
     */
    @Resource
    private CfcVehicleinfoService vehicleinfoService;

    /**
     * 江苏省托运人/货主信息
     */
    @Resource
    private CfcShipperinfoService shipperinfoService;

    /**
     * 江苏省货源信息信息
     */
    @Resource
    private CfcSourcegoodsinfoService sourcegoodsinfoService;
    /**
     * 江苏省运单信息
     */
    @Resource
    private CfcShippingnoteinfoService shippingnoteinfoService;

    /**
     * 江苏省资金流水信息
     */
    @Resource
    private CfcCapitalflowService capitalflowService;

    @Autowired
    private WaybillRouteService waybillRouteService;

    @Override
    public ReportPlatformEnum getReportType() {
        return ReportPlatformEnum.REPORT_PLATFORM_JSV2;
    }

    @Override
    public void checkReport() {
        //江苏监管V2.0平台
        if(!HyCfgUtil.isUsed2("jiangsu_report")){
            throw new JeecgBootException("江苏监管平台未配置参数!");
        }
    }

    @Override
    public Result setReportInfo(HyCompanyConfig hyCompanyConfig) {

        if (StrUtil.isEmpty(hyCompanyConfig.getReportUrl())
                || StrUtil.isEmpty(hyCompanyConfig.getReportUsername())
                || StrUtil.isEmpty(hyCompanyConfig.getReportPublickey())) {
            return Result.error("江苏2.0监管平台未配置参数!");
        }

        this.jsuV2ReportPlatformService.setReportInfo(hyCompanyConfig.getReportUrl(),
                hyCompanyConfig.getReportUsername(),
                hyCompanyConfig.getReportPassword(),
                hyCompanyConfig.getReportPublickey(),
                hyCompanyConfig.getReportAppid(),
                hyCompanyConfig.getReportAppkey(),
                hyCompanyConfig.getReportAppsender(),
                hyCompanyConfig.getReportApprelease());
        return Result.ok("设置成功");
    }

    @Override
    public Result reportShippingNote(HyShippingNote hyShippingNote) {
        Result result = this.checkDriverAndVehicle(hyShippingNote);
        if (!result.getCode().equals(CommonConstant.SC_OK_200)) {
            return result;
        }

        return this.uploadShippingNote(hyShippingNote);
    }

    @Override
    public Result reportCapitalFlow(HyShippingNote hyShippingNote) {
        Result result = this.checkDriverAndVehicle(hyShippingNote);
        if (!result.getCode().equals(CommonConstant.SC_OK_200)) {
            return result;
        }

        return this.uploadCapitalFlow(hyShippingNote);
    }


    //上报运单和资金流水前，先确认司机、车辆的上传状态
    private Result checkDriverAndVehicle(HyShippingNote hyShippingNote) {

        String driverId = hyShippingNote.getDriverId();
        String vehicleId = hyShippingNote.getVehicleId();
        if (StrUtil.isEmpty(driverId)) {
            return Result.error("当前运单司机信息不存在");
        }

        if (StrUtil.isEmpty(vehicleId)) {
            return Result.error("当前运单车辆信息不存在");
        }

        //自动上报司机和车辆配置
        String autoUpload = HyCfgUtil.getCfgItem2("jiangsu_report","auto_upload");

        boolean bDriverUploadStatus = this.hyDriverReportService.checkUploadStatus(driverId, hyShippingNote.getCompanyId(),
                ReportPlatformEnum.REPORT_PLATFORM_JSV2.getCode());
        if (!bDriverUploadStatus) {
            if (StrUtil.isEmpty(autoUpload) || !autoUpload.equals("1")) {
                return Result.error("请先同步司机数据");
            }
            log.warn("司机未上报江苏监管，开始同步司机数据, {}", driverId);
            Result dResult = this.reportDriver(driverId, hyShippingNote.getCompanyId());
            if (!dResult.getCode().equals(CommonConstant.SC_OK_200)) {
                return dResult;
            }
        }

        boolean bVehicleUploadStatus = this.vehicleReportService.checkUploadStatus(vehicleId, hyShippingNote.getCompanyId(),
                ReportPlatformEnum.REPORT_PLATFORM_JSV2.getCode());
        if (!bVehicleUploadStatus) {
            if (StrUtil.isEmpty(autoUpload) || !autoUpload.equals("1")) {
                return Result.error("请先同步车辆数据");
            }
            log.warn("车辆未上报江苏监管，开始同步车辆数据, {}", vehicleId);
            Result vResult = this.reportVehicle(vehicleId, hyShippingNote.getCompanyId());
            if (!vResult.getCode().equals(CommonConstant.SC_OK_200)) {
                return vResult;
            }
        }

        return Result.OK();
    }


    public Result uploadShippingNote(HyShippingNote hyShippingNote) {

        QueryWrapper<HyCustomerCompany> queryWrapperCustomerCompany = new QueryWrapper();
        queryWrapperCustomerCompany.eq("customer_id", hyShippingNote.getCustomerId());
        //查询货主签约
        HyCustomerCompany customerCompany = customerCompanyService.getOne(queryWrapperCustomerCompany);
        HyOrder hyOrder = orderService.getById(hyShippingNote.getOrderId());
        HyDriver hyDriver = driverService.getById(hyShippingNote.getDriverId());
        HyVehicle hyVehicle = vehicleService.getById(hyShippingNote.getVehicleId());
        HyCompany hyCompany = companyService.getById(hyShippingNote.getCompanyId());
        HyCustomer hyCustomer = customerService.getById(hyShippingNote.getCustomerId());

        if (StrUtil.isEmpty(customerCompany.getContractNumber())) {
            throw new JeecgBootException("货主签约合同编号不能为空");
        }

        if (hyShippingNote.getGoodsWeightLoading().compareTo(hyVehicle.getVehicleTonnage()) > 0 ) {
            log.error("江苏V2监管上报超载 货物重量 {} > 核定载质量 {}", hyShippingNote.getGoodsWeightLoading(), hyVehicle.getVehicleTonnage());
            return Result.error("货物重量超过车辆核定载质量，货物重量:" + hyShippingNote.getGoodsWeightLoading() + " ,车辆核定载质量:" + hyVehicle.getVehicleTonnage());
        }

        //如果没有上报过该运单，设置准备开始上报状态
        if (StrUtil.isEmpty(hyShippingNote.getUploadStatus()) || 0 == Integer.valueOf(hyShippingNote.getUploadStatus())) {
            if (!this.updateShippingUploadStatus(hyShippingNote.getId(), JSV2UploadStatusEnum.UPLOAD_START_READY)) {
                hyShippingNote.setReportFailureReason("未上报");
                hyShippingNote.setUploadDate(new Date());
                hyShippingNote.setReportPlatformType(ReportPlatformEnum.REPORT_PLATFORM_JSV2.getCode());
                hyShippingNoteService.updateById(hyShippingNote);
                return Result.error("初始化运单上报信息失败");
            }

            //如果准备开始上传，设置为9
            hyShippingNote.setUploadStatus(JSV2UploadStatusEnum.UPLOAD_START_READY.getStatus());
        }

        //先用高德模拟轨迹查公里数
        if (StrUtil.isEmpty(hyShippingNote.getTransportationDistance())) {
            MapDirectionDTO mapDirectionDTO = this.amapService.getMapGpsOrder(hyOrder);
            if (ObjectUtil.isNotEmpty(mapDirectionDTO)) {
                log.info("江苏2.0上报模拟轨迹公里数， {}", mapDirectionDTO.getDistance());
                hyShippingNote.setTransportationDistance(mapDirectionDTO.getDistance());
            }
        }

        //如果模拟运输距离为空，使用中交接口查询轨迹公里数
        if (StrUtil.isEmpty(hyShippingNote.getTransportationDistance())) {
            log.warn("江苏2.0上报模拟轨迹公里数获取失败，继续使用中交轨迹获取");
            //运单车辆轨迹查询
            String startTime = DateUtils.dateTimeToString(hyShippingNote.getStatusDtLoading());
            String endTime = DateUtils.dateTimeToString(hyShippingNote.getStatusDtUnloading());
            String vehicleColor = StringUtils.isNotEmpty(hyVehicle.getVehiclePlateColorCode()) ? hyVehicle.getVehiclePlateColorCode() : "2";
            WaybillRouteVO waybillRouteVO = this.waybillRouteService.getWaybillRoute(hyVehicle.getVehicleNumber(), vehicleColor, startTime, endTime, "GCJ02");
            if (null == waybillRouteVO || org.springframework.util.CollectionUtils.isEmpty(waybillRouteVO.getPointDataList())) {
                throw new JeecgBootException("江苏2.0上报失败: 该运单没有车辆轨迹！");
            }

            if (StrUtil.isEmpty(waybillRouteVO.getMileage())) {
                throw new JeecgBootException("江苏2.0上报失败: 该运单运输公里数为0");
            }

            hyShippingNote.setTransportationDistance(waybillRouteVO.getMileage());
        }

        //上传承运人运输合同信息
        Result rContract = uploadContract(hyShippingNote, hyCompany, hyDriver);
        if (!rContract.getCode().equals(CommonConstant.SC_OK_200)) {
            this.updateShippingFailureReason(hyShippingNote.getId(), rContract.getMessage());
            return rContract;
        }

        //上传托运人信息
        Result rShipper = uploadShipperInfo(hyShippingNote, hyCustomer);
        if (!rShipper.getCode().equals(CommonConstant.SC_OK_200)) {
            this.updateShippingFailureReason(hyShippingNote.getId(), rShipper.getMessage());
            return rShipper;
        }

        //上传托运人合同信息
        Result rShipperContract = uploadShipperContract(hyShippingNote, hyCustomer, hyCompany, customerCompany, hyDriver);
        if (!rShipperContract.getCode().equals(CommonConstant.SC_OK_200)) {
            this.updateShippingFailureReason(hyShippingNote.getId(), rShipperContract.getMessage());
            return rShipperContract;
        }

        //上传货源信息
        HyOrderDTO hyOrderDTO = new HyOrderDTO();
        BeanUtil.copyProperties(hyOrder, hyOrderDTO, true);
        if (StrUtil.isNotEmpty(hyShippingNote.getInsuranceNo())) {
            //赋值保险单据信息
            InsuranceApplyRecord insuranceApplyRecord = this.insuranceApplyRecordService.getById(hyShippingNote.getInsuranceNo());
            hyOrderDTO.setInsuranceCompany(insuranceApplyRecord.getInsuranceCompany());
            hyOrderDTO.setInsuranceCompanyNumber(insuranceApplyRecord.getInsuranceCompanyNumber());
            hyOrderDTO.setInsurancePolicy(insuranceApplyRecord.getInsurancePolicy());
            hyOrderDTO.setInsuranceUrl(insuranceApplyRecord.getPdfUrl());
        }
        Result rSourceGoods = uploadSourceGoodsInfo(hyShippingNote, customerCompany, hyOrderDTO, hyCustomer);
        if (!rSourceGoods.getCode().equals(CommonConstant.SC_OK_200)) {
            this.updateShippingFailureReason(hyShippingNote.getId(), rSourceGoods.getMessage());
            return rSourceGoods;
        }

        //上传派车单信息
        //兼容老的中间库，因为切客户时司机和车辆都是老系统的ID，关联不上
        String compatibleUpload = HyCfgUtil.getCfgItem2("jiangsu_report","compatible_upload");
        Result rJobOrder = uploadJobOrderInfo(hyShippingNote, hyOrder, hyDriver, hyVehicle, compatibleUpload);
        if (!rJobOrder.getCode().equals(CommonConstant.SC_OK_200)) {
            this.updateShippingFailureReason(hyShippingNote.getId(), rJobOrder.getMessage());
            return rJobOrder;
        }

        //上传车载货物信息
        Result rVehicleGoods = uploadGoodsOfVehicle(hyShippingNote, hyOrder);
        if (!rVehicleGoods.getCode().equals(CommonConstant.SC_OK_200)) {
            this.updateShippingFailureReason(hyShippingNote.getId(), rVehicleGoods.getMessage());
            return rVehicleGoods;
        }

        //上传运单信息
        CfcShippingnoteinfo cfcShippingnoteinfo = shippingnoteinfoService.ShippingNoteTOCfcShippingNoteInfoV2(hyShippingNote, hyDriver);
        cfcShippingnoteinfo.setPlatformcode(this.jsuV2ReportPlatformService.getPlatformCode());
        try {
            String shippingRes = this.jsuV2ReportPlatformService.sendReport(JsV2ReportConstant.SHIPPINGNOTE_UPLOAD, JSONUtil.toJsonStr(cfcShippingnoteinfo));
            R r = JSONUtil.toBean(shippingRes, R.class, true);
            if (r.getCode() == 200) {
                this.updateShippingUploadStatus(hyShippingNote.getId(), JSV2UploadStatusEnum.UPLOAD_SHIPPING_SUCCESS);
                log.info("运单 " + hyShippingNote.getShippingNoteNumber() + "上传运单信息成功");
                return Result.OK();
            } else {
                this.updateShippingUploadStatus(hyShippingNote.getId(), JSV2UploadStatusEnum.UPLOAD_SHIPPING_ERROR);
                this.updateShippingFailureReason(hyShippingNote.getId(), r.getMsg());
                log.warn("运单 " + hyShippingNote.getShippingNoteNumber() + "上传运单信息失败");
                return Result.error(hyShippingNote.getShippingNoteNumber() + "上传运单信息失败: " + r.getMsg());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return Result.error(hyShippingNote.getShippingNoteNumber() + "上传运单信息失败,江苏监管平台连接超时");
    }

    //上传合同信息
    private Result uploadContract(HyShippingNote hyShippingNote, HyCompany company, HyDriver hyDriver) {

        if (Integer.valueOf(hyShippingNote.getUploadStatus()) <= JSV2UploadStatusEnum.UPLOAD_CONTRACT_SUCCESS.getCode().intValue()) {
            log.info("运单 " + hyShippingNote.getShippingNoteNumber() + "已上报合同信息");
            return Result.OK();
        }

        CfcContractinfo cfcContractinfo = shippingnoteinfoService.getContractInfo(hyShippingNote, company, hyDriver);
        cfcContractinfo.setPlatformcode(this.jsuV2ReportPlatformService.getPlatformCode());

        if (StrUtil.isEmpty(cfcContractinfo.getContractnumber())) {
            log.error("运单 " + hyShippingNote.getShippingNoteNumber() + " 承运合同不能为空");
            return Result.error("运单 " + hyShippingNote.getShippingNoteNumber() + " 承运合同不能为空");
        }

        try {
            String contractRes = this.jsuV2ReportPlatformService.sendReport(JsV2ReportConstant.CONTRACT_UPLOAD, JSONUtil.toJsonStr(cfcContractinfo));
            R r = JSONUtil.toBean(contractRes, R.class, true);
            if (r.getCode() == 200 || r.getMsg().contains("重复上传")) {
                this.updateShippingUploadStatus(hyShippingNote.getId(), JSV2UploadStatusEnum.UPLOAD_CONTRACT_SUCCESS);
                log.info("运单 " + hyShippingNote.getShippingNoteNumber() + "上传合同信息成功");
                return Result.OK();
            } else {
                return Result.error("运单 " + hyShippingNote.getShippingNoteNumber() + "上传合同信息失败: " + r.getMsg());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传合同信息失败, {}", e.getMessage());
        }

        return Result.error("运单 " + hyShippingNote.getShippingNoteNumber() + "上传合同信息失败,江苏监管平台连接超时");
    }


    //上传托运人信息
    private Result uploadShipperInfo(HyShippingNote hyShippingNote, HyCustomer customer) {

        if (Integer.valueOf(hyShippingNote.getUploadStatus()) <= JSV2UploadStatusEnum.UPLOAD_CUSTOMER_SUCCESS.getCode().intValue()) {
            log.info("运单 " + hyShippingNote.getShippingNoteNumber() + "已上报托运人信息");
            return Result.OK();
        }

        CfcShipperinfo cfcShipperinfo = shipperinfoService.customerTOShipperinfo(customer);
        cfcShipperinfo.setPlatformcode(this.jsuV2ReportPlatformService.getPlatformCode());
        cfcShipperinfo.setIsblaclklist("0");

        try {
            String shipperRes = this.jsuV2ReportPlatformService.sendReport(JsV2ReportConstant.SHIPPER_UPLOAD, JSONUtil.toJsonStr(cfcShipperinfo));
            R r = JSONUtil.toBean(shipperRes, R.class, true);
            if (r.getCode() == 200 || r.getMsg().contains("重复上传")) {
                this.updateShippingUploadStatus(hyShippingNote.getId(), JSV2UploadStatusEnum.UPLOAD_CUSTOMER_SUCCESS);
                log.info("运单 " + hyShippingNote.getShippingNoteNumber() + "上传托运人信息成功");
                return Result.OK();
            } else {
                return Result.error("运单 " + hyShippingNote.getShippingNoteNumber() + "上传托运人信息失败: " + r.getMsg());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传托运人信息失败, {}", e.getMessage());
        }

        return Result.error("运单 " + hyShippingNote.getShippingNoteNumber() + "上传托运人信息失败,江苏监管平台连接超时");
    }

    //上传托运人合同
    private Result uploadShipperContract(HyShippingNote hyShippingNote, HyCustomer hyCustomer, HyCompany company, HyCustomerCompany customerCompany, HyDriver hyDriver) {

        if (Integer.valueOf(hyShippingNote.getUploadStatus()) <= JSV2UploadStatusEnum.UPLOAD_CUSTOMER_CONTRACT_SUCCESS.getCode().intValue()) {
            log.info("运单 " + hyShippingNote.getShippingNoteNumber() + "已上报托运合同信息");
            return Result.OK();
        }

        CfcContractinfo cfcContractinfo = shippingnoteinfoService.getShipperContractInfo(hyShippingNote,hyCustomer, company, customerCompany, hyDriver);
        cfcContractinfo.setPlatformcode(this.jsuV2ReportPlatformService.getPlatformCode());

        if (StrUtil.isEmpty(cfcContractinfo.getContractnumber())) {
            log.error("运单 " + hyShippingNote.getShippingNoteNumber() + " 托运合同不能为空");
            return Result.error("运单 " + hyShippingNote.getShippingNoteNumber() + " 托运合同不能为空");
        }

        try {
            String contractRes = this.jsuV2ReportPlatformService.sendReport(JsV2ReportConstant.CONTRACT_UPLOAD, JSONUtil.toJsonStr(cfcContractinfo));
            R r = JSONUtil.toBean(contractRes, R.class, true);
            if (r.getCode() == 200 || r.getMsg().contains("重复上传")) {
                this.updateShippingUploadStatus(hyShippingNote.getId(), JSV2UploadStatusEnum.UPLOAD_CUSTOMER_CONTRACT_SUCCESS);
                log.info("运单 " + hyShippingNote.getShippingNoteNumber() + "上传托运合同信息成功");
                return Result.OK();
            } else {
                return Result.error("运单 " + hyShippingNote.getShippingNoteNumber() + "上传托运合同信息失败: " + r.getMsg());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传托运合同信息失败, {}", e.getMessage());
        }

        return Result.error("运单 " + hyShippingNote.getShippingNoteNumber() + "上传托运合同信息失败,江苏监管平台连接超时");
    }

    //上传货源信息
    private Result uploadSourceGoodsInfo(HyShippingNote hyShippingNote, HyCustomerCompany hyCustomerCompany, HyOrderDTO hyOrder, HyCustomer customer) {

        if (Integer.valueOf(hyShippingNote.getUploadStatus()) <= JSV2UploadStatusEnum.UPLOAD_ORDER_SUCCESS.getCode().intValue()) {
            log.info("运单 " + hyShippingNote.getShippingNoteNumber() + "已上报货源信息");
            return Result.OK();
        }

        CfcShipperinfo cfcShipperinfo = shipperinfoService.customerTOShipperinfo(customer);
        CfcSourcegoodsinfo cfcSourcegoodsinfo = sourcegoodsinfoService.hyOrderTOSourcegoodsinfo(hyOrder, cfcShipperinfo);
        cfcSourcegoodsinfo.setPlatformcode(this.jsuV2ReportPlatformService.getPlatformCode());
        cfcSourcegoodsinfo.setContractnumber(hyCustomerCompany.getContractNumber());
        if (0 == cfcSourcegoodsinfo.getItemgrossweight().compareTo(BigDecimal.ZERO)) {
            cfcSourcegoodsinfo.setItemgrossweight(hyShippingNote.getGoodsWeightLoading().setScale(3, BigDecimal.ROUND_HALF_UP));
            cfcSourcegoodsinfo.setTotalmonetaryamount(hyShippingNote.getGoodsWeightLoading().multiply(
                    hyOrder.getShippingUnitPrice()).setScale(3, BigDecimal.ROUND_HALF_UP));
        }

        try {
            String sourceGoodsRes = this.jsuV2ReportPlatformService.sendReport(JsV2ReportConstant.SOURCEGOODS_UPLOAD, JSONUtil.toJsonStr(cfcSourcegoodsinfo));
            R r = JSONUtil.toBean(sourceGoodsRes, R.class, true);
            if (r.getCode() == 200 || r.getMsg().contains("重复上传")) {
                this.updateShippingUploadStatus(hyShippingNote.getId(), JSV2UploadStatusEnum.UPLOAD_ORDER_SUCCESS);
                log.info("运单 " + hyShippingNote.getShippingNoteNumber() + "上传货源信息成功");
                return Result.OK();
            } else {
                return Result.error("运单 " + hyShippingNote.getShippingNoteNumber() + "上传货源信息失败: " + r.getMsg());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传货源信息失败, {}", e.getMessage());
        }

        return Result.error("运单 " + hyShippingNote.getShippingNoteNumber() + "上传货源信息失败,江苏监管平台连接超时");
    }

    //派车单信息
    private Result uploadJobOrderInfo(HyShippingNote hyShippingNote, HyOrder hyOrder, HyDriver hyDriver, HyVehicle hyVehicle, String compatibleUpload) {

        if (Integer.valueOf(hyShippingNote.getUploadStatus()) <= JSV2UploadStatusEnum.UPLOAD_JOBINFO_SUCCESS.getCode().intValue()) {
            log.info("运单 " + hyShippingNote.getShippingNoteNumber() + "已上报派车单信息");
            return Result.OK();
        }

        CfcJoborderinfo cfcJoborderinfo = shippingnoteinfoService.ShippingNoteTOCfcJoborderinfoV2(hyShippingNote, hyOrder, hyDriver, hyVehicle, compatibleUpload);
        cfcJoborderinfo.setPlatformcode(this.jsuV2ReportPlatformService.getPlatformCode());

        try {
            String jobOrderRes = this.jsuV2ReportPlatformService.sendReport(JsV2ReportConstant.JOBORDER_UPLOAD, JSONUtil.toJsonStr(cfcJoborderinfo));
            R r = JSONUtil.toBean(jobOrderRes, R.class, true);
            if (r.getCode() == 200 || r.getMsg().contains("重复上传")) {
                this.updateShippingUploadStatus(hyShippingNote.getId(), JSV2UploadStatusEnum.UPLOAD_JOBINFO_SUCCESS);
                log.info("运单 " + hyShippingNote.getShippingNoteNumber() + "上传派车单信息成功");
                return Result.OK();
            } else {
                return Result.error("运单 " + hyShippingNote.getShippingNoteNumber() + "上传派车单信息失败: " + r.getMsg());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传派车单信息失败, {}", e.getMessage());
        }

        return Result.error("运单 " + hyShippingNote.getShippingNoteNumber() + "上传派车单信息失败,江苏监管平台连接超时");
    }

    //车载货运信息
    private Result uploadGoodsOfVehicle(HyShippingNote hyShippingNote, HyOrder hyOrder) {

        if (Integer.valueOf(hyShippingNote.getUploadStatus()) <= JSV2UploadStatusEnum.UPLOAD_VEHICLEGOODS_SUCCESS.getCode().intValue()) {
            log.info("运单 " + hyShippingNote.getShippingNoteNumber() + "已上报车载货物信息");
            return Result.OK();
        }

        CfcGoodsofvehicle cfcGoodsofvehicle = shippingnoteinfoService.getGoodsOfVehicleInfo(hyShippingNote, hyOrder);
        cfcGoodsofvehicle.setPlatformcode(this.jsuV2ReportPlatformService.getPlatformCode());
        cfcGoodsofvehicle.setIsdeleteflag("0");

        try {
            String goodsOfVehicleRes = this.jsuV2ReportPlatformService.sendReport(JsV2ReportConstant.GOODSVEHICLE_UPLOAD, JSONUtil.toJsonStr(cfcGoodsofvehicle));
            R r = JSONUtil.toBean(goodsOfVehicleRes, R.class, true);
            if (r.getCode() == 200 || r.getMsg().contains("重复上传")) {
                this.updateShippingUploadStatus(hyShippingNote.getId(), JSV2UploadStatusEnum.UPLOAD_VEHICLEGOODS_SUCCESS);
                log.info("运单 " + hyShippingNote.getShippingNoteNumber() + "上传车载货物信息成功");
                return Result.OK();
            } else {
                return Result.error("运单 " + hyShippingNote.getShippingNoteNumber() + "上传车载货物信息失败: " + r.getMsg());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传车载货物信息失败, {}", e.getMessage());
        }

        return Result.error("运单 " + hyShippingNote.getShippingNoteNumber() + "上传车载货物信息失败,江苏监管平台连接超时");
    }


    private boolean updateShippingUploadStatus(String shippingId, JSV2UploadStatusEnum jsv2UploadStatusEnum) {
        return this.hyShippingNoteService.update(new LambdaUpdateWrapper<HyShippingNote>()
                .eq(HyShippingNote::getId, shippingId)
                        .set(HyShippingNote::getReportPlatformType, ReportPlatformEnum.REPORT_PLATFORM_JSV2.getCode())
                .set(HyShippingNote::getUploadStatus, jsv2UploadStatusEnum.getStatus())
                .set(HyShippingNote::getUploadDate, new Date())
        );
    }


    private boolean updateShippingFailureReason(String shippingId, String failureReason) {
        return this.hyShippingNoteService.update(new LambdaUpdateWrapper<HyShippingNote>()
                .eq(HyShippingNote::getId, shippingId)
                .set(HyShippingNote::getReportFailureReason, failureReason)
                .set(HyShippingNote::getUploadDate, new Date())
        );
    }

    public Result uploadCapitalFlow(HyShippingNote hyShippingNote) {

        QueryWrapper<HyCustomerCompany> queryWrapperCustomerCompany = new QueryWrapper();
        queryWrapperCustomerCompany.eq("customer_id", hyShippingNote.getCustomerId());

        HyShippingNote shippingNote = hyShippingNoteService.getById(hyShippingNote.getId());
        if (!shippingNote.getUploadStatus().equals("1")) {
            return Result.error("请先上报运单数据");
        }

        if (!shippingNote.getShippingPayStatus().equals(ShippingPayStatus.支付完成.getValue())) {
            return Result.error("该运单未支付完成");
        }

        //生成派车单号,就是运单号
        CfcJoborderinfo cfcJoborderinfo = new CfcJoborderinfo();
        cfcJoborderinfo.setJobordernumber(hyShippingNote.getShippingNoteNumber());

        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("shipping_id", hyShippingNote.getId());
        queryWrapper.ne("upload_status", "1");
        List<HyShippingNoteBill> shippingNoteBills = hyShippingNoteBillService.list(queryWrapper);
        if (CollectionUtils.isNotEmpty(shippingNoteBills)) {
            try {
                for (HyShippingNoteBill bill : shippingNoteBills) {
                    CfcCapitalflow cfcCapitalflow = this.capitalflowService.getCfcCapitalflow(bill, hyShippingNote, cfcJoborderinfo);
                    cfcCapitalflow.setPlatformcode(this.jsuV2ReportPlatformService.getPlatformCode());

                    String vehicleRes = this.jsuV2ReportPlatformService.sendReport(JsV2ReportConstant.CAPITALFLOW_UPLOAD, JSONUtil.toJsonStr(cfcCapitalflow));
                    R r1 = JSONUtil.toBean(vehicleRes, R.class, true);
                    boolean res = r1.getCode() == 200 ?  true : false;
                    bill.setUploadDate(new Date());
                    bill.setUploadStatus(res ? "1" : "2");
                    bill.setReportFailureReason(res ? "上报成功" : r1.getMsg());
                    bill.setReportPlatformType(ReportPlatformEnum.REPORT_PLATFORM_JSV2.getCode());

                    this.hyShippingNoteBillService.updateById(bill);
                    if (!res) {
                        return Result.error("资金流水单" + bill.getBillNum() + "上传失败: " + r1.getMsg());
                    }
                }

                return Result.OK("上报成功");
            } catch (Exception e) {
                log.info("上报资金流水数据错误，{}", e.getMessage());
                e.printStackTrace();
            }
        }

        return Result.error("上报资金流水数据错误,江苏监管平台连接超时");
    }


    @Override
    public Result reportVehicle(String vehicleId, String companyId) {

        HyVehicle hyVehicle = vehicleService.getById(vehicleId);
        if (null == hyVehicle) {
            return Result.error("未找到车辆数据");
        }

        String driverId = hyVehicle.getDriverId();
        if (StrUtil.isEmpty(driverId)) {
            return Result.error("该车辆未绑定司机");
        }
        //系统目前所属承运人id就是司机id
        hyVehicle.setCarrierId(driverId);

        //载重量上限判断
        if (hyVehicle.getVehicleTonnage().intValue() > 90 ||
                hyVehicle.getVehicleTonnage().compareTo(hyVehicle.getGrossMass()) > -1) {
            throw new JeecgBootException("车辆的核载质量不在有效范围内");
        }

        //吨位上限判断
        if (hyVehicle.getGrossMass().intValue() > 90) {
            throw new JeecgBootException("车辆的总质量不在有效范围内");
        }

        List<HyVehicleType> hyVehicleTypeList = vehicleService.getHyVehicleByPid("1");
        HyVehicleType hyVehicleType = hyVehicleTypeList.stream().filter(s->hyVehicle.getVehicleType().contains(s.getText())).findAny().orElse(null);
        if (hyVehicleType == null) {
            throw new JeecgBootException("车辆类型不存在,请修改后重新上报");
        }
        hyVehicle.setVehicleType(hyVehicleType.getValue());

//        HyVehicleReport hyVehicleReport = new HyVehicleReport();
//        if(!vehicleService.checkRTCNoV2(hyVehicle)){
//            hyVehicleReport.setId(vehicleId);
//            hyVehicleReport.setVehicleId(vehicleId);
//            hyVehicleReport.setReportPlatformType(ReportPlatformEnum.REPORT_PLATFORM_JS.getCode());
//            hyVehicleReport.setVehicleUploadStatus( "2");
//            hyVehicleReport.setUploadDate( new Date() );
//            hyVehicleReport.setVehicleReportFailureReason("车辆道路运输证号不正确或者已过期，请修改后重新上传！");
//            vehicleReportService.saveVehicleReport(hyVehicleReport);
//
//            throw new JeecgBootException("车辆道路运输证号不正确或者已过期，请修改后重新上传！");
//        }

        CfcVehicleinfo cfcVehicleinfo = this.vehicleinfoService.vehicleTOCfcVehicleinfo(hyVehicle);
        cfcVehicleinfo.setPlatformcode(this.jsuV2ReportPlatformService.getPlatformCode());

        HyVehicleReport hyVehicleReport = new HyVehicleReport();
        try {
            String vehicleRes = this.jsuV2ReportPlatformService.sendReport(JsV2ReportConstant.VEHICLE_UPLOAD, JSONUtil.toJsonStr(cfcVehicleinfo));
            R r1 = JSONUtil.toBean(vehicleRes, R.class, true);

            boolean res = r1.getCode() == 200 ? true : false;
            //{"msg":"该车辆已上传，请勿重复上传！","code":501}
            if (r1.getMsg().contains("车辆") && r1.getMsg().contains("重复")) {
                res = true;
            }
            hyVehicleReport.setCompanyId(companyId);
            hyVehicleReport.setVehicleId(vehicleId);
            hyVehicleReport.setReportPlatformType(ReportPlatformEnum.REPORT_PLATFORM_JSV2.getCode());
            hyVehicleReport.setVehicleUploadStatus(res ? "1" : "2");
            hyVehicleReport.setUploadDate(new Date());
            hyVehicleReport.setVehicleReportFailureReason(r1.getMsg() + r1.getData());
            this.vehicleReportService.saveVehicleReport(hyVehicleReport);

            this.vehicleService.updateJsUploadStatusById(vehicleId, hyVehicleReport.getVehicleUploadStatus());
            return res ? Result.OK("同步成功") : Result.error(hyVehicleReport.getVehicleReportFailureReason());

        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传车辆失败, {}", e.getMessage());
        }

        return Result.error("上传车辆信息失败,江苏监管平台连接超时");
    }


    @Override
    public Result reportDriver(String driverId, String companyId) {

        HyDriver hyDriver = this.driverService.getById(driverId);
        if (null == hyDriver) {
            return Result.error("未找到司机信息");
        }

        List<HyVehicle> hyVehicleList = this.vehicleService.getVehicleByDriverId(hyDriver.getId());
        if (CollUtil.isEmpty(hyVehicleList)) {
            return Result.error("未找到该司机所绑定的车辆信息");
        }
        HyVehicle hyVehicle = hyVehicleList.get(0);

        //司机信息
        CfcDriverinfo cfcDriverinfo = this.driverinfoService.driverTOcfcDriverinfo(hyDriver);
        cfcDriverinfo.setPlatformcode(this.jsuV2ReportPlatformService.getPlatformCode());

        //实际承运人
        CfcCarrierinfo cfcCarrierinfo = this.driverinfoService.driverTOcfcCarrierinfo(hyDriver, hyVehicle);
        cfcCarrierinfo.setPlatformcode(this.jsuV2ReportPlatformService.getPlatformCode());

        HyDriverReport hyDriverReport = new HyDriverReport();
        hyDriverReport.setDriverId(driverId);
        hyDriverReport.setReportPlatformType(ReportPlatformEnum.REPORT_PLATFORM_JSV2.getCode());
        hyDriverReport.setCompanyId(companyId);

        try {
            String driverRes = this.jsuV2ReportPlatformService.sendReport(JsV2ReportConstant.DRIVER_UPLOAD, JSONUtil.toJsonStr(cfcDriverinfo));
            R r1 = JSONUtil.toBean(driverRes, R.class, true);
            if (200 != r1.getCode()) {
                //{"msg":"该驾驶员已上传，请勿重复上传！","code":501}
                if (!r1.getMsg().contains("驾驶员") && !r1.getMsg().contains("重复")) {
                    hyDriverReport.setDriverUploadStatus("2");
                    hyDriverReport.setUploadDate(new Date());
                    hyDriverReport.setDriverReportFailureReason(r1.getMsg());
                    hyDriverReportService.saveDriverReport(hyDriverReport);
                    this.driverService.updateJsUploadStatusById(driverId, "2");
                    return Result.error("上传司机失败，监管平台返回信息： " + r1.getMsg());
                }
            }

            String carrierRes = this.jsuV2ReportPlatformService.sendReport(JsV2ReportConstant.CARRIER_UPLOAD, JSONUtil.toJsonStr(cfcCarrierinfo));
            R r2 = JSONUtil.toBean(carrierRes, R.class, true);
            if (200 != r2.getCode()) {
                //{"msg":"该承运人已上传，请勿重复上传！","code":501}
                if (!r2.getMsg().contains("承运人") && !r2.getMsg().contains("重复")) {
                    hyDriverReport.setDriverUploadStatus("2");
                    hyDriverReport.setUploadDate(new Date());
                    hyDriverReport.setDriverReportFailureReason(r2.getMsg());
                    hyDriverReportService.saveDriverReport(hyDriverReport);
                    this.driverService.updateJsUploadStatusById(driverId, "2");
                    return Result.error("上传承运人失败，监管平台返回信息： " + r2.getMsg());
                }
            }

            hyDriverReport.setDriverUploadStatus("1");
            hyDriverReport.setUploadDate(new Date());
            hyDriverReportService.saveDriverReport(hyDriverReport);
            this.driverService.updateJsUploadStatusById(driverId, "1");
            return Result.OK("同步成功");

        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传司机及实际承运人失败, {}", e.getMessage());
        }

        return Result.error("上传司机信息失败,江苏监管平台连接超时");
    }
}
